import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import font_manager as fm

# 设置中文字体路径
font_path = 'E:/下载/SimHei.ttf'  # 替换为字体文件的实际路径
font_prop = fm.FontProperties(fname=font_path)

# 将字体设置为全局默认字体，确保图表中能够显示中文字符
plt.rcParams['font.sans-serif'] = [font_prop.get_name()]
plt.rcParams['axes.unicode_minus'] = False  # 解决负号'-'显示为方块的问题

# 画图的主题设计，使用Seaborn默认主题
sns.set_theme()

# 加载数据集
data_user = pd.read_csv('user_action.csv')

# 数据预处理：将时间列拆分为日期（date）和小时（hour）
data_user['date'] = pd.to_datetime(data_user['time'].str.split(' ').str[0])
data_user['hour'] = data_user['time'].str.split(' ').str[1].astype('int64')

# 转换特定列的数据类型，确保它们的格式正确
data_user = data_user.astype({
    'user_id': 'object',  # 用户ID为字符串类型
    'item_id': 'object',  # 商品ID为字符串类型
    'item_category': 'object',  # 商品类别为字符串类型
    'hour': 'int64'  # 小时为整数类型
})

# 用户购买频次分布直方图
# 计算每个用户的购买频次（行为类型为4代表购买）
data_user_buy = data_user[data_user.behavior_type == 4].groupby('user_id')['behavior_type'].count()

# 绘制用户购买频次分布的直方图
plt.figure(figsize=(10, 6))  # 设置图表大小
plt.hist(data_user_buy, bins=30, color='skyblue', edgecolor='black')  # 绘制直方图，设置颜色和边框颜色
plt.title('用户购买频次分布', fontproperties=font_prop)  # 设置图表标题
plt.xlabel('购买次数', fontproperties=font_prop)  # 设置X轴标签
plt.ylabel('用户数量', fontproperties=font_prop)  # 设置Y轴标签
plt.show()  # 显示图表

# ARPU（每用户平均收入）分析
# 添加一个新列表示每次操作，值为1，用于计算操作次数
data_user['action'] = 1
# 计算每个用户每天的行为次数，并将结果重置索引
data_user_arpu = data_user.groupby(['date', 'user_id', 'behavior_type'])['action'].count().reset_index()

# 计算每日ARPU值，ARPU = 每日购买行为次数 / 每日活跃用户数
arpu = data_user_arpu.groupby('date').apply(
    lambda x: pd.Series({
        'ARPU': x[x['behavior_type'] == 4]['action'].sum() / len(x['user_id'].unique())
    }), include_groups=False
).reset_index()

# 可视化ARPU值
arpu.set_index('date')['ARPU'].plot(colormap='cividis', figsize=(10, 6))  # 设置颜色映射和图表大小
plt.title('ARPU', fontproperties=font_prop)  # 设置图表标题
plt.xlabel('日期', fontproperties=font_prop)  # 设置X轴标签
plt.ylabel('ARPU值', fontproperties=font_prop)  # 设置Y轴标签
plt.show()  # 显示图表

# ARPPU（每付费用户平均收入）分析
# 计算每天每个用户的购买次数，并重命名列名为buy_count
data_user_arppu = data_user[data_user['behavior_type'] == 4].groupby(['date', 'user_id'])[
    'behavior_type'].count().reset_index().rename(columns={'behavior_type': 'buy_count'})

# 计算每日ARPPU值，ARPPU = 每日购买次数 / 每日付费用户数
arppu = data_user_arppu.groupby('date').apply(
    lambda x: pd.Series({
        'ARPPU': x['buy_count'].sum() / x['user_id'].count()
    }), include_groups=False
).reset_index()

# 可视化ARPPU值
arppu.set_index('date')['ARPPU'].plot(colormap='cividis', figsize=(10, 6))  # 设置颜色映射和图表大小
plt.title('ARPPU', fontproperties=font_prop)  # 设置图表标题
plt.xlabel('日期', fontproperties=font_prop)  # 设置X轴标签
plt.ylabel('ARPPU值', fontproperties=font_prop)  # 设置Y轴标签
plt.show()  # 显示图表

# 复购情况分析
# 计算用户购买频次，按用户ID分组，计算每个用户在多少不同日期购买过商品
data_user_pay = data_user[data_user.behavior_type == 4].groupby('user_id')['date'].apply(lambda x: len(x.unique()))
# 计算复购率，复购率 = 有复购行为的用户数 / 总购买用户数
repeat_buy_ratio = data_user_pay[data_user_pay > 1].count() / data_user_pay.count()
print(f"复购率: {repeat_buy_ratio:.2%}")  # 打印复购率

# 复购周期分析
# 计算用户购买行为的日期差值，获得复购周期
data_user_buy = data_user[data_user.behavior_type == 4].groupby(['user_id', 'date'])['action'].count().reset_index()
# 对日期排序，计算前后两次购买的天数差，并去掉空值
data_user_buy_date_diff = data_user_buy.groupby('user_id').date.apply(lambda x: x.sort_values().diff(1).dropna())
# 将天数差转换为整数天数
data_user_buy_date_diff = data_user_buy_date_diff.apply(lambda x: x.days)
# 可视化复购周期的分布
data_user_buy_date_diff.value_counts().sort_index().plot(kind='line', figsize=(10, 6), color='orange')  # 绘制折线图
plt.title('复购周期分析', fontproperties=font_prop)  # 设置图表标题
plt.xlabel('复购周期（天）', fontproperties=font_prop)  # 设置X轴标签
plt.ylabel('用户数量', fontproperties=font_prop)  # 设置Y轴标签
plt.show()  # 显示图表
